﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;

namespace SpeedTest
{
	public partial class PanelExecute : UserControl
	{
		private Data data = null;
		private DataTable caseTable = null;
		private int currRowIndex = 0;
		private string itemID = String.Empty;
		private string parentPlanID = String.Empty;
		private string environID = String.Empty;
		private string activeResultID = String.Empty;

        public event NavigateEvent Navigate;
        public event SaveEvent SaveClicked;

		public PanelExecute(Data data, string itemID, string parentPlanID, string environID)
		{
			InitializeComponent();

			this.data = data;
			this.parentPlanID = parentPlanID;
			this.itemID = itemID;
			this.environID = environID;

			caseTable = data.GetCaseSuiteByID(itemID, NodeType.CaseNode);
			if (caseTable != null && caseTable.Rows.Count > 0)
			{
				browserSteps.DocumentText = LoadCase();
			}
			else
			{
				MessageBox.Show("There are no cases to execute in this set");
				this.Enabled = false;
			}

			DataTable activeResultTable = data.GetActiveResultByCaseID(itemID, environID);
			if (activeResultTable != null && activeResultTable.Rows.Count > 0)
			{
				activeResultID = activeResultTable.Rows[0]["ID"].ToString();
				SetResult(activeResultTable.Rows[0]["Result"].ToString());
			}
		}

		private void SetResult(string result)
		{
			lblExecStatus.Text = result;
			lblExecStatus.BackColor = GetResultColor(result);
		}

		//TODO: this is the same as the function on MainForm - move to util class
		private Color GetResultColor(string result)
		{
			if (!String.IsNullOrEmpty(result))
			{
				switch (result.ToLower())
				{
					case "blocked":
						return Color.Yellow;	//light yellow
					case "failed":
						return Color.Red;	//light red
					case "passed":
						return Color.Green;	//light green
					case "untestable":
						return Color.FromArgb(196, 196, 196);	//light grey
					case "rescheduled":
						return Color.FromArgb(196, 196, 196);
				}
			}

			return Color.White;
		}
		//set the bg color to match the form, regardless of themes
		private string SetDocumentBGColor()
		{
			string r = this.BackColor.R.ToString();
			string g = this.BackColor.G.ToString();
			string b = this.BackColor.B.ToString();
			string style = "background-color: rgb(" + r + ", " + g + ", " + b + ");";

			return style;
		}

		private string LoadCase()
		{
			DataTable steps = null;
			if (!String.IsNullOrEmpty(caseTable.Rows[currRowIndex]["Steps"].ToString()))
			{
				steps = GetTableFromXML(caseTable.Rows[currRowIndex]["Steps"].ToString());
			}
			string title = caseTable.Rows[currRowIndex]["Description"].ToString();
			return GenerateHtmlFromData(steps, title);
		}

		//TODO: this is duplicate of PanelCase.GetTableFromXml- should probably move it to a Util class
		private DataTable GetTableFromXML(string xmlData)
		{
			DataSet set = new DataSet();
			StringReader reader = new StringReader(xmlData);
			set.ReadXml(reader);
			DataTable table = set.Tables[0].Copy();
			return table;
		}

		//operates on the caseTable, using the currRowIndex
		private string GenerateHtmlFromData(DataTable stepsTable, string header)
		{
			XmlDocument doc = new XmlDocument();
			XmlElement htmlElem = doc.CreateElement("HTML");
			XmlElement body = doc.CreateElement("BODY");
			XmlElement div = doc.CreateElement("DIV");
			div.SetAttribute("ALIGN", "Center");
			body.SetAttribute("STYLE", SetDocumentBGColor()); 
			doc.AppendChild(htmlElem);
			htmlElem.AppendChild(div);
			div.AppendChild(body);

			XmlElement titleHeader = doc.CreateElement("H3");
			titleHeader.SetAttribute("STYLE", "text-align: center;");
			titleHeader.InnerText = header;
			body.AppendChild(titleHeader);

			body.AppendChild(doc.CreateElement("BR"));

			if (stepsTable != null)
			{
				XmlElement tableElem = doc.CreateElement("TABLE");
				tableElem.SetAttribute("Style", "text-align: left; width: 80%; margin-left: auto; margin-right: auto;");
				body.AppendChild(tableElem);

				XmlElement tableHeader = doc.CreateElement("THEAD");
				tableElem.AppendChild(tableHeader);
				XmlElement tableRow = doc.CreateElement("TR");
				tableElem.AppendChild(tableRow);

				XmlElement theaderElem;
				foreach (DataColumn col in stepsTable.Columns)
				{
					theaderElem = doc.CreateElement("TH");
					theaderElem.SetAttribute("STYLE", "width: 385px;");
					theaderElem.InnerText = col.ColumnName;
					tableRow.AppendChild(theaderElem);
				}

				// Create table rows.
				XmlElement tableBody = doc.CreateElement("TBODY");
				tableElem.AppendChild(tableBody);
				foreach (DataRow dr in stepsTable.Rows)
				{
					tableRow = doc.CreateElement("TR");
					tableBody.AppendChild(tableRow);
					foreach (DataColumn col in stepsTable.Columns)
					{
						Object dbCell = dr[col];
						XmlElement tableCell = doc.CreateElement("TD");
						tableCell.SetAttribute("STYLE", "width: 385px;");
						if (!(dbCell is DBNull))
						{
							tableCell.InnerText = dbCell.ToString();
						}
						tableRow.AppendChild(tableCell);
					}
				}
			}

			return doc.InnerXml;
		}

		private void btnNext_Click(object sender, EventArgs e)
		{
			Navigate.Invoke(NavigationDirection.Next);
		}

		private void btnPrevious_Click(object sender, EventArgs e)
		{
			Navigate.Invoke(NavigationDirection.Previous);
		}

		private void btnCancel_Click(object sender, EventArgs e)
		{
			//Check for save needed
			//exit execute mode
			ClearInputs();
		}

		private void btnSave_Click(object sender, EventArgs e)
		{
			//post current results
			//unset save needed

			//TODO: Validate entries
			DataTable table = new DataTable();
			table.Columns.Add("PlanID");	
			table.Columns.Add("CaseID");
			table.Columns.Add("EnvironmentID");
			table.Columns.Add("Result");
			table.Columns.Add("ReferenceNumber");
			table.Columns.Add("Notes");
			table.Columns.Add("UserID");
			table.Columns.Add("Active");

			string[] row = new string[8];
			row[0] = parentPlanID;
			row[1] = itemID;
			row[2] = environID;
			if (lstResult.CheckedItems.Count > 0) { row[3] = lstResult.CheckedItems[0].ToString().ToUpper(); }
			row[4] = txtRefNumber.Text;
			row[5] = txtNotes.Text;
			row[6] = data.User.UserID;
			row[7] = "TRUE";

			table.Rows.Add(row);

			if (!String.IsNullOrEmpty(activeResultID)) { data.DeactivateResultByID(activeResultID); }
			activeResultID = data.InsertResult(table).ToString();
			SetResult(row[3]);

			SaveClicked.Invoke(row[3]);
		}

		private void ClearInputs()
		{
			txtRefNumber.Text = String.Empty;
			txtNotes.Text = String.Empty;
			UncheckItems(-1);	//uncheck all
		}

		private void btnAttachments_Click(object sender, EventArgs e)
		{
			AttachmentsForm attachForm = new AttachmentsForm(data, itemID);
			attachForm.ShowDialog();
		}

		private void btnHistory_Click(object sender, EventArgs e)
		{
			HistoryForm histForm = new HistoryForm(data, itemID, environID);
			histForm.ShowDialog();
		}

		private void lstResult_ItemCheck(object sender, ItemCheckEventArgs e)
		{
			//uncheck any others.
			UncheckItems(e.Index);
		}

		private void UncheckItems(int ignoredIndex)
		{
			for (int i = 0; i < lstResult.Items.Count; i++)
			{
				if (i != ignoredIndex)
				{
					lstResult.SetItemChecked(i, false);
				}
			}
		}
	}
}
